﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;

namespace LinqBll
{
    public class DataContextBaseCore<T> : ITableCore<T>
        where T : class,new()
    {
        #region Members
        System.Data.Linq.DataContext Db { get; set; }

        public DataContextBaseCore()
        {

        }
        public DataContextBaseCore(DataContext db)
        {
            if (db == null)
                throw new ArgumentNullException();

            Db = db;
        }

        #endregion


        public Table<T> Table
        {
            get { return this.Db.GetTable<T>(); }
        }

        public void CreateList(IEnumerable<T> ts)
        {
            Table.InsertAllOnSubmit(ts);
            Db.SubmitChanges();
        }

        public void Create(T t)
        {
            Table.InsertOnSubmit(t);
            Db.SubmitChanges();
        }

        public void Delete(T t)
        {
            Table.DeleteOnSubmit(t);
            Db.SubmitChanges();
        }

        public void Update(T t)
        {
            //这里需要区分两种写法
            //1.同一个Context,只需要db.submitchanges()即可
            //2.不同的Context,需要先Attach
            //所以我的写法是捕获异常,不论是否是同一个Context,都需要提交这个submit
            try
            {
                this.Table.Attach(t);
                this.Db.Refresh(RefreshMode.KeepCurrentValues, t);
            }
            catch (Exception)
            {

            }
            finally
            {
                Db.SubmitChanges();
            }
        }

        public System.Collections.Generic.IList<T> Select(int start, int limit)
        {
            return this.Table.Skip(start).Take(limit).ToList();
        }

        public void SaveChanges()
        {
            this.Db.SubmitChanges();
        }

        public void Dispose()
        {
            this.Db.Dispose();
        }



        public void Delete(IEnumerable<T> ts)
        {
            Table.DeleteAllOnSubmit(ts);
            Db.SubmitChanges();
        }

        public void Update(IEnumerable<T> ts)
        {
            try
            {
                Table.AttachAll(ts);
                Db.Refresh(RefreshMode.KeepCurrentValues, ts);
            }
            catch (Exception)
            {
            }
            finally
            {
                Db.SubmitChanges();
            }
        }

        public T Query(Func<T, bool> func)
        {
            return Table.FirstOrDefault(func);
        }

        public IQueryable<T> QueryList()
        {
            return Table.AsQueryable();
        }
        public IQueryable<T> QueryList(Func<T, bool> func)
        {
            if (func == null)
                return Table.AsQueryable();
            return Table.Where(func).AsQueryable();
        }

        public IQueryable<T> QueryList(Func<T, int, bool> func)
        {
            if (func == null)
                return Table.AsQueryable();
            return Table.Where(func).AsQueryable();
        }
    }
}
